package gui;

import java.awt.BorderLayout;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.border.Border;
import javax.swing.border.TitledBorder;

import utils.LIFRandomizer;
import utils.math_utils.RandStream;
import utils.math_utils.RandStream.Rand;


@SuppressWarnings("serial")
class LIFPropertiesPanel extends JPanel {
	
	private static final Rand DEFAULT_IPP_DIST = Rand.GAUSS;
	private static final boolean DEFAULT_IPP_CLIP = true;
	private static final double DEFAULT_IPP_MEAN = 15;
	private static final double DEFAULT_IPP_SD = 2.5;
	private static final double DEFAULT_IPP_MAX = 30;
	private static final double DEFAULT_IPP_MIN = 10;
	private static final double DEFAULT_INITMP_MAX = 15.1;
	private static final double DEFAULT_INITMP_MIN = 13.5;
	private static final double DEFAULT_TIME_CONSTANT = 30;
	private static final double DEFAULT_REST_POTENTIAL = 0;
	private static final double DEFAULT_BACKGROUND = 13.5;
	private static final double DEFAULT_REFRACTORY = 2;
	private static final double DEFAULT_RESISTANCE = 1.0;
	private static final double DEFAULT_THRESHOLD = 15;
	private static final double DEFAULT_RESET = 13.5;
	
	private GridBagLayout layout;
	private JLabel IP = new JLabel("Intrinsic Plasticity:");
	private JLabel tc = new JLabel("Time Const (ms):");
	private JLabel rMP = new JLabel("Rest (mV):");
	private JLabel bgCurr = new JLabel("BG Current (nA):");
	private JLabel ref = new JLabel("Refractory (ms):");
	private JLabel res = new JLabel("Resistance: (M" + "\u03A9" + "):");
	private JLabel thresh = new JLabel("Threshold (mV):");
	private JLabel reset = new JLabel("Reset (mV):");	
	private RandomizerPanel intrinsicP = new RandomizerPanel(
			new RandStream(DEFAULT_IPP_DIST, DEFAULT_IPP_MEAN,
					DEFAULT_IPP_SD, DEFAULT_IPP_MAX, DEFAULT_IPP_MIN,
					DEFAULT_IPP_CLIP));	
	private RandomizerPanel initialMP = new RandomizerPanel(
			new RandStream(DEFAULT_INITMP_MAX, DEFAULT_INITMP_MIN));
	
	private JTextField timeConst = new JTextField(5);
	private JTextField restPot = new JTextField(5);
	private JTextField backCurr = new JTextField(5);
	private JTextField refractory = new JTextField(5);
	private JTextField resistance = new JTextField(5);
	private JTextField threshold = new JTextField(5);
	private JTextField resetP = new JTextField(5);
	private JCheckBox intP = new JCheckBox();
	
	private LIFRandomizer coreRand;
	
	
	public LIFPropertiesPanel() {		
		fillFieldValues();
		addActionListeners();
		initializeLayout();
	}
	
	public void fillFieldValues() {
		
		timeConst.setText(Double.toString(DEFAULT_TIME_CONSTANT));
		restPot.setText(Double.toString(DEFAULT_REST_POTENTIAL));
		backCurr.setText(Double.toString(DEFAULT_BACKGROUND));
		refractory.setText(Double.toString(DEFAULT_REFRACTORY));
		resistance.setText(Double.toString(DEFAULT_RESISTANCE));
		threshold.setText(Double.toString(DEFAULT_THRESHOLD));
		resetP.setText(Double.toString(DEFAULT_RESET));
		intP.setSelected(true);
		
	}
	
	public void initializeLayout() {
		GridBagConstraints gbc = new GridBagConstraints();
		gbc.anchor = GridBagConstraints.WEST;
		gbc.fill = GridBagConstraints.HORIZONTAL;
		gbc.weightx = 1;
		gbc.insets = new Insets(10, 10, 0, 10);
		layout = new GridBagLayout();	
		
		this.setLayout(layout);
		
		gbc.gridx = 0;
		gbc.gridy = 0;
		this.add(tc, gbc);
		gbc.gridx = 1;
		this.add(timeConst, gbc);
		
		gbc.gridy = 1;
		gbc.gridx = 0;
		this.add(rMP, gbc);
		gbc.gridx = 1;
		this.add(restPot, gbc);
		
		gbc.gridy = 2;
		gbc.gridx = 0;
		this.add(ref, gbc);
		gbc.gridx = 1;
		this.add(refractory, gbc);
		
		gbc.gridy = 3;
		gbc.gridx = 0;
		this.add(res, gbc);
		gbc.gridx = 1;
		this.add(resistance,gbc);
		
		gbc.gridy = 4;
		gbc.gridx = 0;
		this.add(thresh,gbc);
		gbc.gridx = 1;
		this.add(threshold, gbc);
		
		gbc.gridy = 5;
		gbc.gridx = 0;
		this.add(bgCurr, gbc);
		gbc.gridx = 1;
		this.add(backCurr, gbc);
		
		gbc.gridy = 6;
		gbc.gridx = 0;
		this.add(reset, gbc);
		gbc.gridx = 1;
		this.add(resetP, gbc);
		
		gbc.gridy = 7;
		gbc.gridx = 0;
		this.add(IP, gbc);
		gbc.gridx = 1;
		this.add(intP, gbc);
		
		Border line = BorderFactory.createEtchedBorder();
		TitledBorder tb = BorderFactory.createTitledBorder(line, "Initial Membrane Potential");
		tb.setTitleJustification(TitledBorder.LEFT);
		initialMP.setBorder(tb);
		
		gbc.gridx = 2;
		gbc.gridy = 0;
		gbc.gridheight = 4;
		gbc.gridwidth = 4;
		this.add(initialMP, gbc);
		
		tb = BorderFactory.createTitledBorder(line, "ISI Distribution");
		tb.setTitleJustification(TitledBorder.LEFT);
		intrinsicP.setBorder(tb);
		
		gbc.gridy = 4;
		this.add(intrinsicP, gbc);
		
		gbc.gridheight = 1;
		gbc.gridwidth = 6;
		gbc.gridx = 0;
		gbc.gridy = 8;

			
	}
	
	public void addActionListeners() {
		
		intP.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent arg0) {
				
				if(intP.isSelected()) {

					intrinsicP.enablePanel();
					repaint();
					
				} else {
					intrinsicP.disablePanel();
				}
			}
			
		});
		
		
		
	}
	
	public LIFRandomizer closeDialogOk() {
		coreRand = new LIFRandomizer();
		coreRand.setMp(initialMP.closeDialogOk());
		if(intP.isSelected())
			coreRand.setRate(intrinsicP.closeDialogOk());
		coreRand.setMEMRES(Double.parseDouble(backCurr.getText()));
		coreRand.setRP(Double.parseDouble(restPot.getText()));
		coreRand.setTC(Double.parseDouble(timeConst.getText()));
		coreRand.setBGCURR(Double.parseDouble(backCurr.getText()));
		coreRand.setREF(Double.parseDouble(refractory.getText()));
		coreRand.setTHRESH(Double.parseDouble(threshold.getText()));
		coreRand.setRESET(Double.parseDouble(resetP.getText()));
		
		return coreRand;
	}
public static void main(String [] args) {
		
		JFrame master = new JFrame();
		master.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		master.add(new LIFPropertiesPanel(), BorderLayout.CENTER);
		
		master.pack();
		master.setVisible(true);
		
	}
	
	
}